#!/usr/bin/python3
# -*- coding: utf-8 -*-
'''
@Author: Phoenix
@Date: 2020-07-20 23:33:35

约定：
① 翻译文本首行一定为：'# TODO: Translation updated at xxx'

② 以下形式的代码块为一个“待处理区块（Block Awaiting Processing，简称BAP）”，即“标识符行 + 原文注释 + 译文”。缓存数以一个BAP为基数
translate chinese xxx_xxx_xxxxxxxx:

    # pov "xxxxx" with dissolve
    pov "" with dissolve

③ 文本在循环扫描时，原文say要先于译文say进行判断处理
'''

import os
from re import escape, match, sub
from sys import exit

import main
from modules.utils import *

# BAP最大缓存量。到达最大缓存量后，将缓存写入文本并清空，然后重新开始计数
_bap_max_cache = GLOBAL_DATA['rpy_update_bap_max_cache']

# 旧版本翻译文本路径
_old_abspath = GLOBAL_DATA['rpy_update_old_abspath']
# 新版本翻译文本路径
_new_abspath = GLOBAL_DATA['rpy_update_new_abspath']
# 更新后的翻译文本路径
_output_abspath = ''

# 标识符缓存库。以标识符作为key进行储存，不可储存who和strings。格式：{identifier:[new_say,new_say]}
_identifier_library_cache = {}
# 文本缓存库。以文本作为key进行储存，可储存who和strings。格式：{old_say:{identifier:[new_say,new_say]}}
_txt_library_cache = {}


def walk_file():
    '''
    遍历文件夹内所有内容
    '''

    if os.path.isfile(_old_abspath):
        root, f = os.path.split(_old_abspath)
        if not f.endswith('.rpy'):
            return

        # 跳过非翻译文本
        if not is_renpy_translation_file(os.path.join(root, f)):
            return

        print(f'当前扫描文本：{f}')
        scanning_file(root, f)
    else:
        for root, dirs, files in os.walk(_old_abspath, topdown=False):
            # 遍历所有文件
            for f in files:
                if not f.endswith('.rpy'):
                    continue

                # 跳过非翻译文本
                if not is_renpy_translation_file(os.path.join(root, f)):
                    continue

                print(f'当前扫描文本：{f}')
                scanning_file(root, f)

    if len(_txt_library_cache) < 1 and len(_identifier_library_cache) < 1:
        return

    if os.path.isfile(_new_abspath):
        root, f = os.path.split(_new_abspath)
        if not f.endswith('.rpy'):
            return

        # 跳过非翻译文本
        if not is_renpy_translation_file(_new_abspath):
            return

        print(f'当前更新文本：{f}')
        process_file(_new_abspath, _output_abspath, f)
        return

    for root, dirs, files in os.walk(_new_abspath, topdown=False):

        # 创建文件所在目录
        relative_path = os.path.relpath(root, _new_abspath)
        output_path = (
            _output_abspath
            if relative_path == '.'
            else os.path.join(_output_abspath, relative_path)
        )
        # 若新目录不存在，创建它
        if not os.path.exists(output_path):
            os.makedirs(output_path)

        # 遍历所有文件
        for f in files:
            if not f.endswith('.rpy'):
                # TODO 非翻译文件直接拷贝至新目录
                continue

            new_path = os.path.join(root, f)
            # 跳过非翻译文本
            if not is_renpy_translation_file(new_path):
                # TODO 非翻译文件直接拷贝至新目录
                continue

            print(f'当前更新文本：{f}')
            process_file(new_path, os.path.join(output_path, f), f)


def scanning_file(file_path: str, filename: str):
    '''
    扫描旧版本文本，将需要的数据存入缓存器
    '''

    inp = open(os.path.join(file_path, filename), 'r', encoding=get_file_encoding(os.path.join(file_path, filename)))
    lightSen = inp.readlines()
    inp.close()

    _old_who = ''  # 字符串形式的who
    _old_say = ''  # 原文say
    _strings_identifier = 'strings'  # strings标识符，用来区分who_say和old_new
    _curr_bap_processed = ''  # 标志当前BAP处理结束

    try:
        for line in lightSen:
            # 空行
            if match(r'^\s*$', line) != None:
                continue

            # 标志符行
            identifier_match = PATTERN_IDENTIFIER.match(line)
            if identifier_match != None:
                _strings_identifier = identifier_match.group(1)
                # 扫描到标志符行，说明进入了新的BAP，清空原文
                # 此步非常重要，避免在没有原文且选择覆盖的情况下出错
                _old_who = ''
                _old_say = ''
                # 重置BAP结束标志
                _curr_bap_processed = False
                continue

            # 原文本行
            old_say_match = PATTERN_OLD_SAY.match(line)
            if old_say_match != None and _strings_identifier not in ['', 'strings']:
                old_say_list = old_say_match.groups()
                _who = old_say_list[0]
                # 跳过cv语音行
                if _who == 'voice':
                    continue

                # 存在字符串形式的who，在存入缓存库之前，不能修改_old_who
                who_match = PATTERN_WHO.match(_who)
                if who_match != None and who_match.group(1) != '':
                    _old_who = who_match.group(1)

                # 获取原文
                _old_say = old_say_list[1]
                continue

            # old行
            old_match = PATTERN_OLD.match(line)
            if old_match != None and _strings_identifier == 'strings':
                # 获取原文，在存入缓存库之前，不能修改_old_say
                _old_say = old_match.group(1)
                _curr_bap_processed = False
                continue

            # 如果当前BAP已处理结束，则不论原译文下面还有多少行，直接进入新的BAP
            if _curr_bap_processed:
                continue

            # 译文行
            new_say_match = PATTERN_NEW_SAY.match(line)
            if new_say_match != None and _strings_identifier not in ['', 'strings']:
                new_say_list = new_say_match.groups()
                _who = new_say_list[0]
                # 跳过cv语音行
                if _who == 'voice':
                    continue

                # 写入标识符缓存库
                new_say = new_say_list[1]
                write_in_identifier_library_cache(_strings_identifier, new_say)

                # 原文say为空时，不写入文本缓存库
                if _old_say == '':
                    continue

                # 字符串形式的who
                who_match = PATTERN_WHO.match(_who)
                if who_match != None and who_match.group(1) != '':
                    write_in_txt_library_cache(_old_who, who_match.group(1), 'who')

                # 写入文本缓存库，并返回当前BAP处理标志
                _curr_bap_processed = write_in_txt_library_cache(
                    _old_say, new_say, _strings_identifier
                )
                continue

            # new 行
            new_match = PATTERN_NEW.match(line)
            if new_match != None and _strings_identifier == 'strings':
                # 写入文本缓存库
                write_in_txt_library_cache(
                    _old_say, new_match.group(1), _strings_identifier
                )
                # 当前BAP处理结束
                _curr_bap_processed = True
                continue

    except Exception as e:
        print_err(
            f'数据读写异常：{e.args[0]}，当前标识符：{_strings_identifier}！'
        )
        print_err(f'{filename} 扫描终止！\n')
        exit(0)
    else:
        print_info(f'{filename} 扫描完成！\n')


def process_file(new_path: str, output_path: str, filename: str):
    '''
    将缓存区中原文相匹配的译文写入到新翻译文本中
    '''

    outp = open(output_path, 'w', encoding=get_file_encoding(output_path))
    inp = open(new_path, 'r', encoding=get_file_encoding(new_path))
    lightSen = inp.readlines()
    inp.close()

    _old_say = ''  # 原文say
    _strings_identifier = 'strings'  # strings标识符，用来区分who_say和old_new
    _tmp_lines = ''  # 缓存文本
    _bap_count = 0  # BAP当前缓存量

    try:
        for line in lightSen:
            # 空行
            if PATTERN_EMPTY_LINE.match(line) != None:
                _tmp_lines += line
                continue

            # 标志符行
            identifier_match = PATTERN_IDENTIFIER.match(line)
            if identifier_match != None:
                _tmp_lines += line
                _strings_identifier = identifier_match.group(1)
                # 进入新的BAP，缓存量+1
                _bap_count += 1
                # 扫描到标志符行，说明进入了新的BAP，原文清空
                # 此步非常重要，避免在没有原文且选择覆盖的情况下出错
                _old_say = ''
                continue

            # 原文本行
            old_say_match = PATTERN_OLD_SAY.match(line)
            if old_say_match != None and _strings_identifier not in ['', 'strings']:
                _tmp_lines += line
                _old_say_list = old_say_match.groups()
                # 跳过cv语音行
                if _old_say_list[0] == 'voice':
                    continue

                _old_say = _old_say_list[1]
                continue

            # 译文行
            new_say_match = PATTERN_NEW_SAY.match(line)
            if new_say_match != None and _strings_identifier not in ['', 'strings']:
                _new_say_list = new_say_match.groups()
                _who = _new_say_list[0]
                # 跳过cv语音行
                if _who == 'voice':
                    _tmp_lines += line
                    continue

                # 原文say为空时，从identifier_library_cache匹配
                if _old_say == '':
                    # 当译文say不为空时，不做改变
                    if _new_say_list[1].strip() != '':
                        _tmp_lines += line
                    else:
                        _list = read_from_identifier_library_cache(_strings_identifier)
                        if len(_list) < 1:
                            _tmp_lines += line
                        else:
                            # transition
                            with_transition = _new_say_list[2]
                            for item in _list:
                                _tmp_lines += (
                                    '    '
                                    + ((_who + ' ') if _who != '' else _who)
                                    + '\"'
                                    + item
                                    + '\"'
                                    + (
                                        (' ' + with_transition)
                                        if with_transition != ''
                                        else with_transition
                                    )
                                    + '\n'
                                )
                    if _bap_count >= _bap_max_cache:
                        outp.write(_tmp_lines)
                        outp.flush()
                        _tmp_lines = ''
                        # 清空BAP缓存
                        _bap_count = 0
                    # 当前BAP处理结束，若当前BAP的译文是多行翻译，除第一行外均删除
                    _old_say = END_SAY
                    continue

                # 新翻译文本翻译以原翻译文本翻译为准，新翻译文本中当前BAP第二行起翻译均舍弃
                if _old_say == END_SAY:
                    continue

                # who
                who_match = PATTERN_WHO.match(_who)
                if who_match != None and who_match.group(1) != '':
                    original_new_who = who_match.group(1)
                    _list = read_from_txt_library_cache(original_new_who, 'who')
                    if len(_list) > 0:
                        _who = sub(
                            escape(repr(original_new_who))[1:-1], _list[0], _who, 1
                        )

                # 当译文say不为空时，不做改变
                if _new_say_list[1].strip() != '':
                    _tmp_lines += line
                else:
                    _list = read_from_identifier_library_cache(_strings_identifier)
                    # 如果从identifier_library_cache未匹配到，可以通过标识符在txt_library_cache中再匹配一次
                    if len(_list) < 1:
                        _list = read_from_txt_library_cache(
                            _old_say, _strings_identifier
                        )
                        if len(_list) < 1:
                            _tmp_lines += line
                        else:
                            # transition
                            with_transition = _new_say_list[2]
                            for item in _list:
                                _tmp_lines += (
                                    '    '
                                    + ((_who + ' ') if _who != '' else _who)
                                    + '\"'
                                    + item
                                    + '\"'
                                    + (
                                        (' ' + with_transition)
                                        if with_transition != ''
                                        else with_transition
                                    )
                                    + '\n'
                                )
                    else:
                        # transition
                        with_transition = _new_say_list[2]
                        for item in _list:
                            _tmp_lines += (
                                '    '
                                + ((_who + ' ') if _who != '' else _who)
                                + '\"'
                                + item
                                + '\"'
                                + (
                                    (' ' + with_transition)
                                    if with_transition != ''
                                    else with_transition
                                )
                                + '\n'
                            )
                if _bap_count >= _bap_max_cache:
                    outp.write(_tmp_lines)
                    outp.flush()
                    _tmp_lines = ''
                    # 清空BAP缓存
                    _bap_count = 0
                # 当前BAP处理结束，若当前BAP的译文是多行翻译，除第一行外均删除
                _old_say = END_SAY
                continue

            # old行
            old_match = PATTERN_OLD.match(line)
            if old_match != None and _strings_identifier == 'strings':
                _tmp_lines += line
                _old_say = old_match.group(1)
                continue

            # new 行
            new_match = PATTERN_NEW.match(line)
            if new_match != None and _strings_identifier == 'strings':
                if _old_say == '':
                    _tmp_lines += line
                    if _bap_count >= _bap_max_cache:
                        outp.write(_tmp_lines)
                        outp.flush()
                        _tmp_lines = ''
                        # 清空BAP缓存
                        _bap_count = 0
                    continue

                original_new_say = new_match.group(1)  # 译文
                # 当译文不为空时，如果覆盖写入，则发出请求
                if original_new_say != '':
                    _tmp_lines += line
                else:
                    _list = read_from_txt_library_cache(_old_say, _strings_identifier)
                    if len(_list) < 1:
                        _tmp_lines += line
                    else:
                        _tmp_lines += '    new \"' + _list[0] + '\"\n'
                if _bap_count >= _bap_max_cache:
                    outp.write(_tmp_lines)
                    outp.flush()
                    _tmp_lines = ''
                    # 清空BAP缓存
                    _bap_count = 0
                _old_say = ''
                continue

            # 其他行
            _tmp_lines += line
    except Exception as e:
        print_err(
            f'数据读写异常：{e.args[0]}，当前标识符：{_strings_identifier}！'
        )
        print_err(f'{filename} 更新终止！\n')
        exit(0)
    else:
        if _tmp_lines != '':
            outp.write(_tmp_lines)
        print_info(f'{filename} 更新完成！\n')
    finally:
        outp.close()


def write_in_identifier_library_cache(identifier='', translated_txt=''):
    '''
    写入标识符缓存库
    '''

    # 如果标识符为空或who或strings，不写入缓存库
    identifier = identifier.strip()
    if identifier in ['', 'who', 'strings']:
        return

    # 如果译文为空，或译文中含有TODO，不写入缓存库，已写入缓存库的也删除
    if translated_txt.strip() == '' or TODO_MARK in translated_txt:
        if identifier in _identifier_library_cache:
            del_key_from_dict(_identifier_library_cache, identifier)
        return

    if not identifier in _identifier_library_cache:
        _identifier_library_cache[identifier] = [translated_txt]
    else:
        _identifier_library_cache[identifier].append(translated_txt)


def write_in_txt_library_cache(
    source_txt='', translated_txt='', identifier='strings'
) -> bool:
    '''
    写入文本缓存库
    '''

    # 如果原文为空，直接返回
    if source_txt.strip() == '':
        return True

    # 如果标识符为空，表明数据非法，直接返回
    identifier = identifier.strip()
    if identifier == '':
        return True

    # 去除首尾空行，who和strings的空行往往都是有意而为，故不剔除
    if not identifier in ['who', 'strings']:
        source_txt = source_txt.strip()

    # 将文本全部转为大写。这里需要判断下原字符串是否含有小写英文字符。
    q_upper = ''
    if has_lower_letter(source_txt):
        q_upper = source_txt.upper()

    # 如果译文为空，或译文中含有TODO，不写入缓存库，已写入缓存库的也删除
    if translated_txt.strip() == '' or TODO_MARK in translated_txt:
        if not identifier in ['who', 'strings']:
            if (
                source_txt in _txt_library_cache
                and identifier in _txt_library_cache[source_txt]
            ):
                del_key_from_dict(_txt_library_cache[source_txt], identifier)
            if (
                q_upper
                and q_upper in _txt_library_cache
                and identifier in _txt_library_cache[q_upper]
            ):
                del_key_from_dict(_txt_library_cache[q_upper], identifier)
        return True

    if not source_txt in _txt_library_cache:
        _txt_library_cache[source_txt] = {}
    # 相同文本有可能存在不同标识符，也表示有可能存在不同的翻译，所以要通过标识符进行分别储存
    if not identifier in _txt_library_cache[source_txt]:
        # 译文行存在一条原文对应多条译文的情况，所以这里应该用列表来储存译文
        _txt_library_cache[source_txt][identifier] = [translated_txt]
    else:
        if not identifier in ['who', 'strings']:
            _txt_library_cache[source_txt][identifier].append(translated_txt)

    # 原文本无大写形式时，直接return
    if not q_upper:
        return False

    # 将文本转为大写后再储存一遍，增加匹配成功几率
    if not q_upper in _txt_library_cache:
        _txt_library_cache[q_upper] = {}
    if not identifier in _txt_library_cache[q_upper]:
        _txt_library_cache[q_upper][identifier] = [translated_txt]
    else:
        if not identifier in ['who', 'strings']:
            _txt_library_cache[q_upper][identifier].append(translated_txt)

    return False


def read_from_identifier_library_cache(identifier: str) -> list:
    '''
    从标识符缓存库读取
    '''

    identifier = identifier.strip()
    if identifier in ['', 'who', 'strings']:
        return []

    if identifier in _identifier_library_cache:
        txt_list = _identifier_library_cache[identifier]
        for txt in txt_list:
            if txt.startswith(TODO_MARK):
                return []
        return txt_list

    # 当标识符不匹配时，有可能因存在label不同导致标识符不同的情况，将标识符分割获取8位标识符后再匹配一次
    ident = get_identifier(identifier)
    if not ident == 'wrong':
        for key in _identifier_library_cache:
            cache_ident = get_identifier(key)
            if cache_ident == 'wrong':
                continue
            if ident == cache_ident:
                texs = _identifier_library_cache[key]
                for tex in texs:
                    if tex.startswith(TODO_MARK):
                        return []
                return texs

    return []


def read_from_txt_library_cache(source_txt: str, identifier: str) -> list:
    '''
    从文本缓存库读取

    1. 直接匹配文本。匹配成功，则根据标识符获取译文；若为找到相应标识符，则选择首位索引下的译文
    2. 将文本所有字母转为大写再进行匹配
    '''

    if source_txt.strip() == '':
        return []

    # 去除首尾空行
    identifier = identifier.strip()
    if identifier == '':
        return []

    # 去除首尾空行，strings下的空行往往都是有意而为，故不剔除
    if identifier != 'strings':
        source_txt = source_txt.strip()

    if not source_txt in _txt_library_cache:
        source_txt = source_txt.upper()
        if not source_txt in _txt_library_cache:
            return []

    li = _txt_library_cache[source_txt]
    if len(li) < 1:
        return []

    if identifier in li:
        txt_list = li[identifier]
        for txt in txt_list:
            if txt.startswith(TODO_MARK):
                return []
        return txt_list

    # 当标识符不匹配时，有可能因存在label不同导致标识符不同的情况，将标识符分割获取8位标识符后再匹配一次
    if not identifier in ['who', 'strings']:
        ident = get_identifier(identifier)
        if ident == 'wrong':
            return []

        for key in li:
            cache_ident = get_identifier(key)
            if cache_ident == 'wrong':
                continue
            if ident == cache_ident:
                texs = li[key]
                for tex in texs:
                    if tex.startswith(TODO_MARK):
                        return []
                return texs

    for key in list(li.keys()):
        txt_list = li[key]
        succ = True
        for txt in txt_list:
            if txt.startswith(TODO_MARK):
                succ = False
                break
        if not succ:
            continue
        return li[key]

    return []


def get_identifier(ident: str) -> str:
    '''
    获取除“strings”外的8位标识符，标识符有可能是纯字母、纯数字或字母数字。

    将标识符字符串通过“_”分割成多个字符后，一般最后一位便是8位标识符。
    但同时也存在多个文本相同且都在同一个label语句中的情况，Ren'Py会在标识符行末尾添加一个递增数字来加以区分，此时倒数第二位才是8位标识符。

    如果标识符不是“strings”，且长度不符合标准标识符的位数，那么说明该标识符可能出现了错误，不处理该数据。
    '''
    ident = ident.strip()
    if ident == '':
        return 'wrong'

    ident_split = ident.split('_')
    if len(ident_split) <= 1:
        return ident

    # 末尾值要么是标识符，要么是递增数字，先获取它
    identifier_last = ident_split[-1]

    # 递增数字长度达到8的几率可以忽略不计，故可以认为只要长度等于8，便是我们要找的8位标识符，直接返回结果
    if len(identifier_last) == 8:
        return identifier_last

    # 如果不是纯数字，或长度大于2（文本中出现两位数以上的相同标识符的可能性微乎其微），则将其归为错误数据，返回错误标记
    if not is_int(identifier_last) or len(identifier_last) > 2:
        return 'wrong'

    # 如果是纯数字，则大概率是递增数字，此时我们获取倒数第二位
    identifier = ident_split[-2]
    # 如果倒数第二位的长度依然不等于8，则将其归为错误数据，返回错误标记
    if len(identifier) != 8:
        return 'wrong'

    # 返回8位标识符+递增数字
    return identifier + '_' + identifier_last


def input_path(folder_type='OLD', t='0'):
    '''
    输入待翻文件/文件夹的绝对路径
    '''

    global _old_abspath, _new_abspath, _output_abspath

    if t == '0':
        inp = ''
        if folder_type == 'OLD':
            # 若存在默认路径
            if _old_abspath != '':
                # 若路径不存在，重新手动输入
                if not os.path.exists(_old_abspath):
                    print_err('config.ini配置的旧翻译文本路径不存在！\n')
                    _old_abspath = ''
                    input_path(folder_type)
                    return

                print_info('路径验证成功！\n')
                return

            inp = input('请输入旧翻译文本的绝对路径：').strip()
            # 输入为空，重新输入
            if inp == '':
                input_path(folder_type, '1')
                return
            # 规范路径，不调整大小写
            inp = os.path.normpath(inp)
            # 若路径不存在，重新输入
            if not os.path.exists(inp):
                input_path(folder_type, '1')
                return
            _old_abspath = inp

        elif folder_type == 'NEW':
            # 若存在默认路径
            if _new_abspath != '':
                # 若路径不存在，则重新手动输入
                if not os.path.exists(_new_abspath):
                    print_err('config.ini配置的新翻译文本路径不存在！\n')
                    _new_abspath = ''
                    input_path(folder_type)
                    return

                # 若新翻译文本路径为文件夹，则输出路径也为文件夹
                if os.path.isdir(_new_abspath):
                    _output_abspath = _new_abspath + '-new'
                    # 如果输出文件夹已存在，先将其更名，再新建空文件夹
                    if os.path.exists(_output_abspath):
                        os.rename(
                            _output_abspath,
                            _output_abspath
                            + '_'
                            + datetime.now().strftime('%Y_%m_%d_%H_%M'),
                        )
                    os.makedirs(_output_abspath)
                # 若新翻译文本路径是文件，则输出路径也为文件
                elif os.path.isfile(_new_abspath):
                    _inp = os.path.splitext(_new_abspath)
                    _output_abspath = _inp[0] + '-new' + _inp[-1]
                    # 如果输出文件已存在，将其更名备份
                    if os.path.exists(_output_abspath):
                        (
                            os.rename(
                                _inp[0] + '-new',
                                _inp[0]
                                + '-new_'
                                + datetime.now().strftime('%Y_%m_%d_%H_%M'),
                            )
                            + _inp[-1]
                        )
                print_info('路径验证成功！\n')
                return

            inp = input('请输入新翻译文本的绝对路径：').strip()
            # 输入为空，重新输入
            if inp == '':
                input_path(folder_type, '1')
                return
            # 规范路径，不调整大小写
            inp = os.path.normpath(inp)
            # 若路径不存在，重新输入
            if not os.path.exists(inp):
                input_path(folder_type, '1')
                return
            _new_abspath = inp
            # 若新翻译文本路径为文件夹，则输出路径也为文件夹
            if os.path.isdir(_new_abspath):
                _output_abspath = _new_abspath + '-new'
                # 如果输出文件夹已存在，先将其更名，再新建空文件夹
                if os.path.exists(_output_abspath):
                    os.rename(
                        _output_abspath,
                        _output_abspath
                        + '_'
                        + datetime.now().strftime('%Y_%m_%d_%H_%M'),
                    )
                os.makedirs(_output_abspath)
            # 若新翻译文本路径是文件，则输出路径也为文件
            elif os.path.isfile(_new_abspath):
                _inp = os.path.splitext(_new_abspath)
                _output_abspath = _inp[0] + '-new' + _inp[-1]
                # 如果输出文件已存在，将其更名备份
                if os.path.exists(_output_abspath):
                    (
                        os.rename(
                            _inp[0] + '-new',
                            _inp[0]
                            + '-new_'
                            + datetime.now().strftime('%Y_%m_%d_%H_%M'),
                        )
                        + _inp[-1]
                    )
        print_info('路径验证成功！\n')
        return

    tmp = input('不存在该路径，请重新输入正确的路径或回车关闭程序：').strip()
    # 输入为空，退出程序
    if tmp == '':
        exit(0)
    # 规范路径，不调整大小写
    tmp = os.path.normpath(tmp)
    # 若路径不存在，重新输入
    if not os.path.exists(tmp):
        input_path(folder_type, '1')
        return

    if folder_type == 'OLD':
        _old_abspath = tmp
    else:
        _new_abspath = tmp
        # 若新翻译文本路径为文件夹，则输出路径也为文件夹
        if os.path.isdir(_new_abspath):
            _output_abspath = _new_abspath + '-new'
            # 如果输出文件夹已存在，先将其更名，再新建空文件夹
            if os.path.exists(_output_abspath):
                os.rename(
                    _output_abspath,
                    _output_abspath + '_' + datetime.now().strftime('%Y_%m_%d_%H_%M'),
                )
            os.makedirs(_output_abspath)
        # 若新翻译文本路径是文件，则输出路径也为文件
        elif os.path.isfile(_new_abspath):
            _inp = os.path.splitext(_new_abspath)
            _output_abspath = _inp[0] + '-new' + _inp[-1]
            # 如果输出文件已存在，将其更名备份
            if os.path.exists(_output_abspath):
                (
                    os.rename(
                        _inp[0] + '-new',
                        _inp[0] + '-new_' + datetime.now().strftime('%Y_%m_%d_%H_%M'),
                    )
                    + _inp[-1]
                )
    print_info('路径验证成功！\n')


def _select_serial_num(reselect=False, serial_num=''):
    '''
    输入序号选择对应的操作
    '''

    if not reselect:
        print(
            '''1) 更新翻译文本
0) 返回上一级
'''
        )

        _inp = input('请输入要操作的序号：').strip()
        if _inp == '1':
            return
        if _inp == '0':
            main.start_main()
        else:
            _select_serial_num(True, _inp)
        return

    _tmp = input(
        f'列表中不存在序号 {serial_num}，请重新输入正确序号或回车退出程序：'
    ).strip()
    if _tmp == '':
        exit(0)

    if _tmp == '1':
        return
    if _tmp == '0':
        main.start_main()
    else:
        _select_serial_num(True, _tmp)


def start():

    print(
        r'''
======================================================================
                       Ren'Py 翻译文本更新工具
                            作者：Phoenix
                            版权归作者所有
                  PS：本工具所有操作均不会影响原文件！
======================================================================
'''
    )

    _select_serial_num()

    input_path('OLD')
    input_path('NEW')

    print('正在更新翻译文本中，请稍候……\n')
    walk_file()
    print_info('翻译文本更新已完成！')
    exit(0)
